<?php
namespace app\shop\library\order;

use cubox\Cubox;
use app\shop\library\Lock;
class Stock{
    
    const NUM_KEY = 'shop-stock-num:';
    

    public static function reduce(array $goodsList){

        if (!Lock::$isLocked){
            throw new \Exception('请先获取锁');
        }
        
        $cache =  Cubox::app('shop')->cache();
        
        $count = count($goodsList);
        //查看库存是否够
        foreach($goodsList as $goodsItem){

            $key = self::NUM_KEY.$goodsItem['goods_id'];
            if (isset($goodsItem['sku_id']) && $goodsItem['sku_id']!=''){
                if ($cache->exists($key)){
                    $num = $cache->hGet($key,$goodsItem['sku_id']);
                }else{
                    $num = self::updateGoodsSkuNum($goodsItem['sku_id']);
                    $cache->hSet($key,$goodsItem['sku_id'],$num);
                }

                if ($num>=$goodsItem['num']){
                    $count --;
                }
            }else{
                if ($cache->exists($key)){
                    $num  = $cache->get($key);
                }else{
                    $num = self::updateGoodsNum($goodsItem['goods_id']);
                    $cache->set($key,$num);
                }
    
                if ($num>=$goodsItem['num']){
                    $count --;
                }
            }
        }
        if ($count==0){
            //扣除库存
            foreach($goodsList as $goodsItem){
                $key = self::NUM_KEY.$goodsItem['goods_id'];
                $cache->decr($key,$goodsItem['num']);
            }

            return true;
        }else{
            return false;
        }
    }

    public static function recovery(array $goodsList){
        
        if (!lock::$isLocked){
            throw new \Exception('请先获取锁');
        }

        $cache =  Cubox::app('shop')->cache();

        foreach($goodsList as $goodsItem){
            $key = self::NUM_KEY.$goodsItem['goods_id'];
            $cache->incr($key,$goodsItem['num']);
        }
    }

    private static function updateGoodsSkuNum($sku_id){
        $goodsSku = Cubox::app('shop')->model('GoodsSku');

        $goodsSkuData = $goodsSku->getId($sku_id);
        
        $stockAt = $goodsSkuData['stock_at']??0;

        $orderSum = Cubox::app('shop')->model('OrderGoods')->where('created_at','>',$stockAt)->where('sku_id',$sku_id)->sum('num');

        if (!$orderSum) $orderSum = 0;
        
        if ($orderSum==0){
            return $goodsSkuData['stock']??0;
        } 
        else{
            
            $num = $goodsSkuData['stock']-$orderSum;
           
            //更新库存
            $update = [
                'stock' => $num,
                'stock_at' =>date('Y-m-d H:i:s'),
                'sales' => $goodsSkuData['sales'] + $orderSum
            ];

            $goodsSku->updateId($sku_id,$update);
            return $num;
        }
    }

    private static function updateGoodsNum($goods_id){

        $goods = Cubox::app('shop')->model('Goods');

        $goodsData = $goods->getId($goods_id);

        $stockAt = $goodsData['stock_at']??0;

        //判断一共卖了多少个
        $orderSum = Cubox::app('shop')->model('OrderGoods')->where('created_at','>',$stockAt)->where('goods_id',$goods_id)->sum('num');

        if (!$orderSum) $orderSum = 0;
        
        if ($orderSum==0) return $goodsData['stock'];
        else{
            
            $num = $goodsData['stock']-$orderSum;
           
            //更新库存
            $update = [
                'stock' => $num,
                'stock_at' =>date('Y-m-d H:i:s'),
                'sales' => $goodsData['sales'] + $orderSum
            ];
            
            $goods->updateId($goods_id,$update);
            return $num;
        }

    }

    public static function getGoodsNum($goods_id){
        $cache =  Cubox::app('shop')->cache();
        $key = self::NUM_KEY.$goods_id;
        if ($cache->exists($key)){
            $num  = $cache->get($key);
        }else{
            $num = self::updateGoodsNum($goods_id);
            $cache->set($key,$num);
        }

        return $num;
    }

    public static function getGoodsSkuNum($goods_id,$sku_id){
        static $cacheGoodsData= [];

        if (isset($cacheGoodsData[$goods_id]) && isset($cacheGoodsData[$goods_id][$sku_id])){
            return  $cacheGoodsData[$goods_id][$sku_id];
        }

        $cache =  Cubox::app('shop')->cache();
        $key = self::NUM_KEY.$goods_id;
        if ($cache->exists($key)){
            $cacheGoodsData[$goods_id] = $cache->hGetAll($key);
            if (isset($cacheGoodsData[$goods_id][$sku_id])){
                return  $cacheGoodsData[$goods_id][$sku_id];
            }
        }

        $num = self::updateGoodsSkuNum($sku_id);
        $cache->hSet($key,$sku_id,$num);
        if (!isset($cacheGoodsData[$goods_id])) $cacheGoodsData[$goods_id] = [];
        $cacheGoodsData[$goods_id][$sku_id] = $num;
        return $num;
        
    }
}